﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NB_Controller_Test
{
    public enum E_EventID
    {
        [Description("复位事件")]
        Reset_Event = 0,

        #region 事件定义
        [Description("NB网络连接事件")]
        NB_NetLink_Event,

        [Description("Wifi连接事件")]
        WifiLink_Event,

        [Description("OTA升级事件")]
        OTA_Event,

        [Description("调光输出请求事件")]
        LevelOutput_Event,

        [Description("开关输出请求事件")]
        OnOff_Event,

        [Description("计量电压值波动10V事件")]
        ADC_Vol_10V_Event,

        [Description("计量电流值波动20mA事件")]
        ADC_Cur_20mA_Event,

        [Description("计量功率值波动5W事件")]
        ADC_Pow_5W_Event,

        [Description("计量漏电流波动20mA事件")]
        IDC_Cur_20mA_Event,

        [Description("告警事件")]
        Alarm_Event,

        [Description("设备初始化故障")]
        DevInitError_Event,

        [Description("设备运行故障")]
        DevRunError_Event,

        [Description("事件日志溢出故障")]
        LogOutofMemoryError_Event,

        [Description("NB信号强度波动5dbm")]
        NB_Rssi_5dbm_Event,

        [Description("NB信噪比波动10")]
        NB_Rsrp_10_Event,

        [Description("底层驱动继电器事件")]
        Inside_Switch_Event,

        [Description("底层驱动pwm输出事件")]
        Inside_PWM_Event,

        [Description("启动保存历史运行时间")]
        StartSaveHisRunTime_Event,

        [Description("NB联网信息(1)")]
        NB_LinkNet_Info1_Event,

        [Description("NB联网信息(2)")]
        NB_LinkNet_Info2_Event,

        [Description("NB联网信息(3)")]
        NB_LinkNet_Info3_Event,

        [Description("IOT连接状态")]
        IOT_Link_Status_Event,

        [Description("NB获取网络时间和历史运行时间")]
        NB_GetNetAndHisRunTime_Event,

        [Description("NB发送数据超时事件")]
        NB_SendData_Timeout_Event,

        [Description("同一个数据包NB首次发送失败事件")]
        NB_SendData_First_Timeout_Event
        #endregion
    }

    public enum E_ResetType
    {
        [Description("coap连接超时重启复位")]
        Coap_Reset = 0,
        #region
        [Description("ota升级后复位")]
        OTA_Reset,

        [Description("命令行复位")]
        CMD_Reset,

        [Description("上电复位")]
        Power_Reset,

        [Description("异常复位")]
        Unknown_Reset,
        #endregion
        [Description("软件看门狗复位")]
        User_WDT_Reset,
    }

    public enum E_CPU_ResetType
    {
        [Description("Vbat power on reset")]
        CPU_Reset_Type_1 = 1,

        #region

        [Description("Software reset digital core")]
        CPU_Reset_Type_3 = 3,

        [Description("Legacy watch dog reset digital core")]
        CPU_Reset_Type_4 = 4,

        [Description("Deep Sleep reset digital core")]
        CPU_Reset_Type_5 = 5,

        [Description("Reset by SLC module, reset digital core")]
        CPU_Reset_Type_6 = 6,

        [Description("Timer Group0 Watch dog reset digital core")]
        CPU_Reset_Type_7 = 7,

        [Description("Timer Group1 Watch dog reset digital core")]
        CPU_Reset_Type_8 = 8,

        [Description("RTC Watch dog Reset digital core")]
        CPU_Reset_Type_9 = 9,

        [Description("Instrusion tested to reset CPU")]
        CPU_Reset_Type_10 = 10,

        [Description("Time Group reset CPU")]
        CPU_Reset_Type_11 = 11,

        [Description("Software reset CPU")]
        CPU_Reset_Type_12 = 12,

        [Description("RTC Watch dog Reset CPU")]
        CPU_Reset_Type_13 = 13,

        [Description("for APP CPU, reseted by PRO CPU")]
        CPU_Reset_Type_14 = 14,

        [Description("Reset when the vdd voltage is not stable")]
        CPU_Reset_Type_15 = 15,
        #endregion

        [Description("RTC Watch dog reset digital core and rtc module")]
        CPU_Reset_Type_16 = 16
    }

    public enum E_Oper_Src
    {
        [Description("NB通信控制")]
        NB_Src = 0,
        #region
        [Description("Wifi通信控制")]
        Wifi_Src,

        [Description("命令行控制")]
        CLI_Src,

        [Description("定时计划控制")]
        TIME_Src,

        [Description("启动操作")]
        Boot_Src,

        [Description("测试")]
        Test_Src,
        #endregion
        [Description("未知")]
        Unkonwn_Src,
    }

    public enum E_NB_RegStatus
    {
        #region
        [Description("Not registered, UE is not currently searching an operator to register to")]
        NB_LinkStatus_0 = 0,

        [Description("Registered, home network")]
        NB_LinkStatus_1,

        [Description("Not registered, but UE is currently trying to attach or searching an operator to register to")]
        NB_LinkStatus_2,

        [Description("Registration denied")]
        NB_LinkStatus_3,

        [Description("Unknown (e.g. out of E-UTRAN coverage)")]
        NB_LinkStatus_4,

        [Description("NRegistered, roaming")]
        NB_LinkStatus_5
#endregion

        //0: Not registered, UE is not currently searching an operator to register to
        //1: Registered, home network
        //2: Not registered, but UE is currently trying to attach or searching an operator to 
        //register to
        //3: Registration denied
        //4: Unknown (e.g. out of E-UTRAN coverage)
        //5: Registered, roaming
    }

    public enum E_NB_SendData_Error
    {
        #region
        [Description("[3]Operation not allowed")]
        NB_SendData_Error_3 = 3,

        [Description("[4]Operation not supported")]
        NB_SendData_Error_4 = 4,

        [Description("[5]Need to enter PIN")]
        NB_SendData_Error_5 = 6,

        [Description("[23]Memory failure")]
        NB_SendData_Error_23 = 23,

        [Description("[30]No network service")]
        NB_SendData_Error_30 = 30,

        [Description("[50]Incorrect parameters")]
        NB_SendData_Error_50 = 50,

        [Description("[51]Command implemented but currently disabled")]
        NB_SendData_Error_51 = 51,

        [Description("[52]Command aborted by user")]
        NB_SendData_Error_52 = 52,

        [Description("[100]Unknown")]
        NB_SendData_Error_100 = 100,

        [Description("[159]Uplink busy/flow control ")]
        NB_SendData_Error_159 = 159,

        [Description("[300]ME failure")]
        NB_SendData_Error_300 = 300,

        [Description("[301]SMS service of ME reserved ")]
        NB_SendData_Error_301 = 301,

        [Description("[302]Operation not allowed")]
        NB_SendData_Error_302 = 302,

        [Description("[303]Operation not supported")]
        NB_SendData_Error_303 = 303,

        [Description("[304]Invalid PDU mode parameter")]
        NB_SendData_Error_304 = 304,

        [Description("[305]Invalid text mode parameter")]
        NB_SendData_Error_305 = 305,

        [Description("[310]USIM not inserted")]
        NB_SendData_Error_310 = 310,

        [Description("[311]USIM PIN required")]
        NB_SendData_Error_311 = 311,

        [Description("[312]PH-USIM PIN required")]
        NB_SendData_Error_312 = 312,

        [Description("[313]USIM failure")]
        NB_SendData_Error_313 = 313,

        [Description("[314]USIM busy")]
        NB_SendData_Error_314 = 314,

        [Description("[315]USIM wrong")]
        NB_SendData_Error_315 = 315,

        [Description("[316]USIM PUK required")]
        NB_SendData_Error_316 = 316,

        [Description("[317]USIM PIN2 required")]
        NB_SendData_Error_317 = 317,

        [Description("[318]USIM PUK2 required")]
        NB_SendData_Error_318 = 318,

        [Description("[320]Memory failure")]
        NB_SendData_Error_320 = 320,

        [Description("[321]Invalid memory index")]
        NB_SendData_Error_321 = 321,

        [Description("[322]Memory full")]
        NB_SendData_Error_322 = 322,

        [Description("[330]SMSC address unknown")]
        NB_SendData_Error_330 = 330,

        [Description("[331]No network service")]
        NB_SendData_Error_331 = 331,

        [Description("[332]Network timeout")]
        NB_SendData_Error_332 = 332,

        [Description("[340]No +CNMA acknowledgement expected")]
        NB_SendData_Error_340 = 340,

        [Description("[500]Unknown error ")]
        NB_SendData_Error_500 = 500,

        [Description("[512]Required parameter not configured")]
        NB_SendData_Error_512 = 512,

        [Description("[513]TUP not registered")]
        NB_SendData_Error_513 = 513,

        [Description("[514]AT internal error")]
        NB_SendData_Error_514 = 514,

        [Description("[515]CID is active")]
        NB_SendData_Error_515 = 515,

        [Description("[516]Incorrect state for command")]
        NB_SendData_Error_516 = 516,

        [Description("[517]CID is invalid")]
        NB_SendData_Error_517 = 517,

        [Description("[518]CID is not active")]
        NB_SendData_Error_518 = 518,

        [Description("[520]Deactivate the last active CID")]
        NB_SendData_Error_520 = 520,

        [Description("[521]CID is not defined")]
        NB_SendData_Error_521 = 521,

        [Description("[522]UART parity error")]
        NB_SendData_Error_522 = 522,

        [Description("[523]UART frame error")]
        NB_SendData_Error_523 = 523,

        [Description("[524]UE is in minimal function mode (AT+CFUN=0)")]
        NB_SendData_Error_524 = 524,

        [Description("[525]AT command aborted: in processing")]
        NB_SendData_Error_525 = 525,

        [Description("[526]AT command aborted: error")]
        NB_SendData_Error_526 = 526,

        [Description("[527]Command interrupted")]
        NB_SendData_Error_527 = 527,

        [Description("[528]Configuration conflicts")]
        NB_SendData_Error_528 = 528,

        [Description("[529]During FOTA updating")]
        NB_SendData_Error_529 = 529,

        [Description("[530]Not the AT allocated socket")]
        NB_SendData_Error_530 = 530,

        [Description("[531]USIM PIN is blocked")]
        NB_SendData_Error_531 = 531,

        [Description("[532]USIM PUK is blocked ")]
        NB_SendData_Error_532 = 532,

        [Description("[10001]参数错误或报文大于512字节")]
        NB_SendData_Error_10001 = 10001,

        [Description("[10002]数据发送串口写失败")]
        NB_SendData_Error_10002 = 10002,

        [Description("[10003]数据发送串口没有返回值")]
        NB_SendData_Error_10003 = 10003,

        [Description("[10004]数据发送串口返回值不包括OK和CME")]
        NB_SendData_Error_10004 = 10004
        #endregion

        //3: Operation not allowed
        //4: Operation not supported
        //5: Need to enter PIN
        //23: Memory failure
        //30: No network service
        //50: Incorrect parameters
        //51: Command implemented but currently disabled
        //52: Command aborted by user
        //100: Unknown
        //159: Uplink busy/flow control 
        //300: ME failure
        //301: SMS service of ME reserved 
        //302: Operation not allowed
        //303: Operation not supported
        //304: Invalid PDU mode parameter
        //305: Invalid text mode parameter
        //310: USIM not inserted
        //311: USIM PIN required
        //312: PH-USIM PIN required
        //313: USIM failure
        //314: USIM busy
        //315: USIM wrong
        //316: USIM PUK required
        //317: USIM PIN2 required
        //318: USIM PUK2 required
        //320: Memory failure
        //321: Invalid memory index
        //322: Memory full
        //330: SMSC address unknown
        //331: No network service
        //332: Network timeout
        //340: No +CNMA acknowledgement expected
        //500: Unknown error 
        //512: Required parameter not configured
        //513: TUP not registered
        //514: AT internal error
        //515: CID is active
        //516: Incorrect state for command
        //517: CID is invalid
        //518: CID is not active
        //520: Deactivate the last active CID
        //521: CID is not defined
        //522: UART parity error
        //523: UART frame error
        //524: UE is in minimal function mode (AT+CFUN=0)
        //525: AT command aborted: in processing
        //526: AT command aborted: error
        //527: Command interrupted
        //528: Configuration conflicts
        //529: During FOTA updating
        //530: Not the AT allocated socket
        //531: USIM PIN is blocked
        //532: USIM PUK is blocked 
        //10001: 参数错误或报文大于512字节
        //10002: 数据发送串口写失败
        //10003: 数据发送串口没有返回值
        //10004: 数据发送串口返回值不包括OK和CME
    }

    public enum E_LWM2M_Event
    {
        #region
        [Description("Register complete")]
        LWM2M_Event_0 = 0,

        [Description("Deregister complete")]
        LWM2M_Event_1,

        [Description("Update register complete")]
        LWM2M_Event_2,

        [Description("Object observe complete")]
        LWM2M_Event_3,

        [Description("Bootstrap complete")]
        LWM2M_Event_4,

        [Description("5/0/3 resource observe complete")]
        LWM2M_Event_5,

        [Description("Notify the device to receive update package URL")]
        LWM2M_Event_6,

        [Description("Notify the device to receive update message")]
        LWM2M_Event_7,

        [Description("Cancel object 19/0/0 observe")]
        LWM2M_Event_8
        #endregion

        //0: Register complete
        //1: Deregister complete
        //2: Update register complete
        //3: Object observe complete
        //4: Bootstrap complete
        //5: 5/0/3 resource observe complete
        //6: Notify the device to receive update package URL
        //7: Notify the device to receive update message
        //9: Cancel object 19/0/0 observe
    }

    public enum E_EventType
    {
        [Description("错误事件")]
        Error = 1,

        [Description("警告事件")]
        Warnning = 2,

        [Description("信息事件")]
        Info = 3
    }

    public class EventLog
    {
        #region
        public string strImei;
        //public string strLogIP;
        public string strOriLogData;
        public string strHexOriLogData;
        public string strAnalyData;
        public string strDate;

        public UInt16 usLogID;
        public Byte byHour;
        public Byte byMin;
        public Byte bySecond;
        public Byte byEventID;
        public UInt32 unEventParam;
        public UInt16 usReserve_ForLogDate;
        public UInt32 unReserve_ForLogID;

        public Boolean bPredictTime;

        public E_EventType eventType;

        public string strEventIDInfo;
        public string strEventParamInfo;
        #endregion
    }

    public class EventLogManager
    {
        public static List<EventLog> MakeEventLog(JObject jObj)
        {
            #region 协议描述
            //JSon数据体内，Log信息用3*4个字节来表示，大端对齐
            //0~1   2个字节表示LogID
            //2~4   2个字节表示时分秒
            //5     1个字节表示事件ID
            //6~9   4个字节表示事件参数
            //10~11 预留

            //大端字节序
            //[ 806815058, 16777522, 0 ] -> [ 0x30170552, 0x01000132, 0x00000000 ] 
            //LogID      0x0552
            //时         0x17    
            //分         0x30
            //秒         0x32        高位为1表示预估时间
            //EventID    0x01
            //EventParam 0x0100 0000
            //保留       0x0000

            //其中第4字节高位为1表示预估时间
            #endregion

            #region 数据获取，异常返回
            if (jObj == null)
                return null;

            JToken jtCmdData = jObj.SelectToken("cmdData");
            if (jtCmdData == null)
            {
                //判断可能是测试平台拷贝的数据
                JToken jtContent = jObj.SelectToken("content");
                if (jtContent == null)
                    return null;
                else
                {
                    jtCmdData = jtContent.SelectToken("cmdData");
                    if (jtCmdData == null)
                        return null;
                }
            }
            else
            {
                //Wifi 纯数据，继续
            }

            JToken jtDate = jtCmdData.SelectToken("date");
            JToken jtSeqNo = jtCmdData.SelectToken("seqNo");
            //aPkt
            JToken jtAPkt = jtCmdData.SelectToken("aPkt");
            if (jtDate == null)                
            {
                if (jtSeqNo == null)
                {
                    return null;
                }
                else
                {
                    //应该是根据序号读取
                }
                //return null;
            }
            else
            {
                //可以继续
            }

            JToken jtLogs = jtCmdData.SelectToken("logs");
            if (jtLogs == null)
                return null;
            #endregion

            #region 构建EventLog
            List<EventLog> eventLogs = new List<EventLog>();

            string[] condition = { "]," };
            string[] condition1 = { "," };
            string strLogs = jtLogs.ToString();
            string[] strLogArray = strLogs.Split(condition, StringSplitOptions.None);
            foreach (string strLog in strLogArray)
            {
                string strLogTemp = strLog.Replace("[", "");
                strLogTemp = strLogTemp.Replace("\r\n", "");
                strLogTemp = strLogTemp.Replace(" ", "");
                strLogTemp = strLogTemp.Trim();

                //JArray jArray = JArray.Parse(strLogs);

                EventLog eventLog = new EventLog();
                eventLog.strOriLogData = strLogTemp;
                //判断是根据时间读取还是根据序号读取
                if (jtDate == null)
                {
                    //根据序号读取
                    string[] strValueArray = strLogTemp.Split(condition1, StringSplitOptions.None);
                    if (strValueArray.Length == 4)
                    {
                        #region
                        //0
                        string strValue = strValueArray[0];
                        //strValue = strValue.Replace("]]", "");
                        Int32 nValue = GlobalFun.StringToInt32(strValue);
                        string strHexValue = nValue.ToString("X8");//无法自动补齐不足位 String.Format("{0:X4}", unValue);

                        eventLog.strHexOriLogData = "0x" + strHexValue;

                        Byte byMouth = GlobalFun.HexStringToByte(strHexValue.Substring(0, 2));
                        Byte byYear = GlobalFun.HexStringToByte(strHexValue.Substring(2, 2));                        

                        //eventLog.byMin = GlobalFun.HexStringToByte(strHexValue.Substring(0, 2));
                        //eventLog.byHour = GlobalFun.HexStringToByte(strHexValue.Substring(2, 2));
                        eventLog.usLogID = GlobalFun.HexStringToUInt16(strHexValue.Substring(4, 4));

                        eventLog.strAnalyData = "{月-0x" + byMouth.ToString("X2");
                        eventLog.strAnalyData += (" 年-0x" + byYear.ToString("X2"));
                        eventLog.strAnalyData += (" LogID-0x" + eventLog.usLogID.ToString("X4"));


                        //1
                        strValue = strValueArray[1];
                        //strValue = strValue.Replace("]]", "");
                        nValue = GlobalFun.StringToInt32(strValue);
                        strHexValue = nValue.ToString("X8");

                        eventLog.strHexOriLogData += (",0x" + strHexValue);

                        //UInt16 usV = GlobalFun.HexStringToUInt16(strHexValue.Substring(0, 4));
                        //eventLog.unEventParam = (UInt32)(usV & 0x0000FFFF);
                        //eventLog.byEventID = GlobalFun.HexStringToByte(strHexValue.Substring(4, 2));
                        Byte byDay = GlobalFun.HexStringToByte(strHexValue.Substring(6, 2));
                        //构建日期
                        eventLog.strDate = byYear.ToString() + "-" + byMouth.ToString() + "-" + byDay.ToString();

                        eventLog.byHour = GlobalFun.HexStringToByte(strHexValue.Substring(4, 2));
                        eventLog.byMin = GlobalFun.HexStringToByte(strHexValue.Substring(2, 2));                        
                        eventLog.bySecond = GlobalFun.HexStringToByte(strHexValue.Substring(0, 2));

                        eventLog.strAnalyData += (", 日-0x" + byDay.ToString("X2"));
                        eventLog.strAnalyData += (", H-0x" + eventLog.byHour.ToString("X2"));
                        eventLog.strAnalyData += (", M-0x" + eventLog.byMin.ToString("X2"));
                        eventLog.strAnalyData += (", S-0x" + eventLog.bySecond.ToString("X2"));
                        //eventLog.strAnalyData += (", S-0x" + eventLog.bySecond.ToString("X2"));
                        //eventLog.strAnalyData += (" EventID-0x" + eventLog.byEventID.ToString("X2"));                        

                        if (eventLog.bySecond >> 7 == 0x01)
                        {
                            eventLog.bPredictTime = true;

                            //重新设置秒数
                            eventLog.bySecond &= 0x3C;
                        }
                        else
                        {
                            eventLog.bPredictTime = false;
                        }

                        //2
                        strValue = strValueArray[2];
                        //strValue = strValue.Replace("]]", "");
                        nValue = GlobalFun.StringToInt32(strValue);
                        strHexValue = nValue.ToString("X8");

                        eventLog.strHexOriLogData += (",0x" + strHexValue);

                        eventLog.byEventID = GlobalFun.HexStringToByte(strHexValue.Substring(6, 2));
                        switch ((E_EventID)eventLog.byEventID)
                        {
                            case E_EventID.ADC_Vol_10V_Event:
                            case E_EventID.ADC_Cur_20mA_Event:
                            case E_EventID.ADC_Pow_5W_Event:
                            case E_EventID.IDC_Cur_20mA_Event:
                            case E_EventID.NB_SendData_Timeout_Event:
                            case E_EventID.NB_SendData_First_Timeout_Event:
                                {
                                    //认为是警告
                                    eventLog.eventType = E_EventType.Warnning;
                                }
                                break;
                            case E_EventID.Reset_Event:
                            case E_EventID.Alarm_Event:
                            case E_EventID.DevInitError_Event:
                            case E_EventID.DevRunError_Event:
                            case E_EventID.LogOutofMemoryError_Event:
                                {
                                    //认为是错误
                                    eventLog.eventType = E_EventType.Error;
                                }
                                break;
                            default:
                                {
                                    eventLog.eventType = E_EventType.Info;
                                }
                                break;
                        }
                        //事件ID信息
                        eventLog.strEventIDInfo = ((E_EventID)eventLog.byEventID).ToDescription();

                        UInt32 unV = GlobalFun.HexStringToUInt32(strHexValue.Substring(0, 6));
                        eventLog.unEventParam = (UInt32)(unV & 0x00FFFFFF);
                        

                        //3
                        strValue = strValueArray[3];
                        strValue = strValue.Replace("]]", "");
                        nValue = GlobalFun.StringToInt32(strValue);
                        strHexValue = nValue.ToString("X8");

                        eventLog.strHexOriLogData += (",0x" + strHexValue);

                        UInt32 unValue1 = (UInt32)GlobalFun.HexStringToUInt16(strHexValue.Substring(6, 2)) << 24;
                        eventLog.unEventParam = eventLog.unEventParam | (UInt32)((UInt32)GlobalFun.HexStringToUInt16(strHexValue.Substring(6, 2)) << 24 & 0xFF000000);
                        eventLog.unReserve_ForLogID = GlobalFun.HexStringToUInt32(strHexValue.Substring(0, 6));
                        //eventLog.usReserve = GlobalFun.HexStringToByte(strHexValue.Substring(0, 4));
                        //eventLog.unEventParam = eventLog.unEventParam | (UInt32)((UInt32)GlobalFun.HexStringToUInt16(strHexValue.Substring(4, 4)) << 16 & 0xFFFF0000);
                        //传输时是大端，含义还要转换为小端
                        byte[] bytes = BitConverter.GetBytes(eventLog.unEventParam);
                        Array.Reverse(bytes);
                        string strEventParam = GlobalFun.ByteArrayToHexString(bytes);
                        eventLog.unEventParam = GlobalFun.HexStringToUInt32(strEventParam);


                        eventLog.strAnalyData += (", EventParam-0x" + eventLog.unEventParam.ToString("X8"));
                        eventLog.strAnalyData += (" Reserve-0x" + eventLog.unReserve_ForLogID.ToString("X6"));
                        eventLog.strAnalyData += "}";

                        //事件参数信息
                        eventLog.strEventParamInfo = "0x" + eventLog.unEventParam.ToString("X8");

                        MakeEventLogDetailInfo(eventLog);

                        eventLogs.Add(eventLog);
                        #endregion
                    }
                    else
                    {
                        //数据格式不合法
                        System.Diagnostics.Debug.WriteLine(strValueArray.ToString());
                    }
                }
                else
                {
                    //日期
                    eventLog.strDate = jtDate.ToString();

                    #region
                    string[] strValueArray = strLogTemp.Split(condition1, StringSplitOptions.None);
                    if (strValueArray.Length == 3)
                    {
                        //0
                        string strValue = strValueArray[0];
                        Int32 nValue = GlobalFun.StringToInt32(strValue);
                        string strHexValue = nValue.ToString("X8");//无法自动补齐不足位 String.Format("{0:X4}", unValue);

                        eventLog.strHexOriLogData = "0x" + strHexValue;

                        eventLog.byMin = GlobalFun.HexStringToByte(strHexValue.Substring(0, 2));
                        eventLog.byHour = GlobalFun.HexStringToByte(strHexValue.Substring(2, 2));
                        eventLog.usLogID = GlobalFun.HexStringToUInt16(strHexValue.Substring(4, 4));
                        //if (eventLog.usLogID == 316)
                        //{
                        //    eventLog.usLogID = eventLog.usLogID;
                        //}

                        eventLog.strAnalyData = "{M-0x" + eventLog.byMin.ToString("X2");
                        eventLog.strAnalyData += (" H-0x" + eventLog.byHour.ToString("X2"));
                        eventLog.strAnalyData += (" LogID-0x" + eventLog.usLogID.ToString("X4"));


                        //1
                        strValue = strValueArray[1];
                        nValue = GlobalFun.StringToInt32(strValue);
                        strHexValue = nValue.ToString("X8");

                        eventLog.strHexOriLogData += (",0x" + strHexValue);

                        //UInt16 usV = GlobalFun.HexStringToUInt16(strHexValue.Substring(0, 4));
                        //UInt32 unV = (UInt32)(usV << 0);// << 16
                        UInt16 usV = GlobalFun.HexStringToUInt16(strHexValue.Substring(0, 4));
                        //eventLog.unEventParam = (UInt32)(unV & 0xFFFF0000);
                        eventLog.unEventParam = (UInt32)(usV & 0x0000FFFF);
                        eventLog.byEventID = GlobalFun.HexStringToByte(strHexValue.Substring(4, 2));
                        eventLog.bySecond = GlobalFun.HexStringToByte(strHexValue.Substring(6, 2));

                        eventLog.strAnalyData += (", S-0x" + eventLog.bySecond.ToString("X2"));
                        eventLog.strAnalyData += (" EventID-0x" + eventLog.byEventID.ToString("X2"));

                        switch ((E_EventID)eventLog.byEventID)
                        {
                            case E_EventID.ADC_Vol_10V_Event:
                            case E_EventID.ADC_Cur_20mA_Event:
                            case E_EventID.ADC_Pow_5W_Event:
                            case E_EventID.IDC_Cur_20mA_Event:
                            case E_EventID.NB_SendData_Timeout_Event:
                            case E_EventID.NB_SendData_First_Timeout_Event:
                                {
                                    //认为是警告
                                    eventLog.eventType = E_EventType.Warnning;
                                }
                                break;
                            case E_EventID.Reset_Event:
                            case E_EventID.Alarm_Event:
                            case E_EventID.DevInitError_Event:
                            case E_EventID.DevRunError_Event:
                            case E_EventID.LogOutofMemoryError_Event:
                                {
                                    //认为是错误
                                    eventLog.eventType = E_EventType.Error;
                                }
                                break;
                            default:
                                {
                                    eventLog.eventType = E_EventType.Info;
                                }
                                break;
                        }
                        //事件ID信息
                        eventLog.strEventIDInfo = ((E_EventID)eventLog.byEventID).ToDescription();

                        if (eventLog.bySecond >> 7 == 0x01)
                        {
                            eventLog.bPredictTime = true;

                            //重新设置秒数
                            eventLog.bySecond &= 0x3C;
                        }
                        else
                        {
                            eventLog.bPredictTime = false;
                        }

                        //2
                        strValue = strValueArray[2];
                        strValue = strValue.Replace("]]", "");
                        nValue = GlobalFun.StringToInt32(strValue);
                        strHexValue = nValue.ToString("X8");

                        eventLog.strHexOriLogData += (",0x" + strHexValue);

                        eventLog.usReserve_ForLogDate = GlobalFun.HexStringToByte(strHexValue.Substring(0, 4));
                        eventLog.unEventParam = eventLog.unEventParam | (UInt32)((UInt32)GlobalFun.HexStringToUInt16(strHexValue.Substring(4, 4)) << 16 & 0xFFFF0000);
                        //传输时是大端，含义还要转换为小端
                        byte[] bytes = BitConverter.GetBytes(eventLog.unEventParam);
                        Array.Reverse(bytes);
                        string strEventParam = GlobalFun.ByteArrayToHexString(bytes);
                        eventLog.unEventParam = GlobalFun.HexStringToUInt32(strEventParam);



                        eventLog.strAnalyData += (", EventParam-0x" + eventLog.unEventParam.ToString("X8"));
                        eventLog.strAnalyData += (" Reserve-0x" + eventLog.usReserve_ForLogDate.ToString("X4"));
                        eventLog.strAnalyData += "}";

                        //事件参数信息
                        eventLog.strEventParamInfo = "0x" + eventLog.unEventParam.ToString("X8");

                        MakeEventLogDetailInfo(eventLog);

                        eventLogs.Add(eventLog);
                    }
                    else
                    {
                        //数据格式不合法
                        System.Diagnostics.Debug.WriteLine(strValueArray.ToString());
                    }
                    #endregion
                } 
            }
            #endregion

            //根据EventID排序，若需要
            //若存在预估时间，则根据后续的真实时间来反推
            //foreach (EventLog eventLog in eventLogs)
            //{
            //    if (eventLog.bPredictTime == true)
            //    {

            //    }
            //}
            return eventLogs;
        }

        private static bool MakeEventLogDetailInfo(EventLog eventLog)
        {
            //所有的4字节Int都是需要反转一次，即从后往前一次是3 2 1 0
            switch ((E_EventID)eventLog.byEventID)
            {
                case E_EventID.Reset_Event:
                    {
                        //Byte0：复位原因，详见附表，Byte1-2:CPU(0,1)复位原因
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);
                        string strByte1 = strEventParam.Substring(4, 2);
                        string strByte2 = strEventParam.Substring(2, 2);

                        Byte byByte0 = GlobalFun.HexStringToByte(strByte0);
                        Byte byByte1 = GlobalFun.HexStringToByte(strByte1);
                        Byte byByte2 = GlobalFun.HexStringToByte(strByte2);

                        eventLog.strEventParamInfo = "复位原因: [" + (byByte0).ToString() + "]" + ((E_ResetType)byByte0).ToDescription();
                        eventLog.strEventParamInfo += "\r\nCPU_0复位原因: [";
                        eventLog.strEventParamInfo += (byByte1).ToString();
                        eventLog.strEventParamInfo += "]";
                        eventLog.strEventParamInfo += ((E_CPU_ResetType)byByte1).ToDescription();
                        //eventLog.strEventParamInfo += (byByte1).ToString();
                        eventLog.strEventParamInfo += "\r\nCPU_1复位原因: [";
                        eventLog.strEventParamInfo += (byByte2).ToString();
                        eventLog.strEventParamInfo += "]";
                        eventLog.strEventParamInfo += ((E_CPU_ResetType)byByte2).ToDescription();
                        //eventLog.strEventParamInfo += (byByte2).ToString();
                    }
                    break;
                case E_EventID.NB_NetLink_Event:
                    {
                        //Byte0：类型，0：基站连接事件，1：服务器连接事件； 
                        //Byte1：连接状态，0：断开，1：连接

                        //2019-8-15 含义变化？？？王涛
                        //Byte0：连接状态，0：断开，1：连接； 
                        //Byte1 : REG状态 状态是啥？？？ 据王涛--NB注册状态
                        //string strEventParam = eventLog.unEventParam.ToString("X8");
                        //string strByte0 = strEventParam.Substring(6, 2);
                        //string strByte1 = strEventParam.Substring(4, 2);

                        //eventLog.strEventParamInfo = "类型: ";
                        //eventLog.strEventParamInfo += strByte0 == "00" ? "基站连接事件" : "服务器连接事件";
                        //eventLog.strEventParamInfo += "\r\n连接状态: ";
                        //eventLog.strEventParamInfo += strByte1 == "0" ? "断开" : "连接";

                        //2019-8-15
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);
                        string strByte1 = strEventParam.Substring(4, 2);

                        Byte byByte0 = GlobalFun.HexStringToByte(strByte0);
                        Byte byByte1 = GlobalFun.HexStringToByte(strByte1);

                        eventLog.strEventParamInfo = "连接状态: [" + (byByte0).ToString() + "]";
                        eventLog.strEventParamInfo += strByte0 == "00" ? "断开" : "连接";
                        eventLog.strEventParamInfo += "\r\nNB注册状态: [" + (byByte1).ToString() + "]" + ((E_NB_RegStatus)byByte1).ToDescription(); ;
                    }
                    break;
                case E_EventID.WifiLink_Event:
                    {
                        //Byte0：连接状态，0：断开，1：连接
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);

                        Byte byByte0 = GlobalFun.HexStringToByte(strByte0);

                        eventLog.strEventParamInfo = "连接状态: [" + (byByte0).ToString() + "]";
                        eventLog.strEventParamInfo += strByte0 == "00" ? "断开" : "连接";
                    }
                    break;
                case E_EventID.OTA_Event:
                    {
                        //Byte0：升级状态，0：未升级，1：升级中，2：升级成功，3：升级失败
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);

                        Byte byByte0 = GlobalFun.HexStringToByte(strByte0);

                        eventLog.strEventParamInfo = "连接状态: [" + (byByte0).ToString() + "]";// +strByte0 == "0" ? "断开" : "连接";
                        switch (strByte0)
                        {
                            case "00":
                                eventLog.strEventParamInfo += "未升级";
                                break;
                            case "01":
                                eventLog.strEventParamInfo += "升级中";
                                break;
                            case "02":
                                eventLog.strEventParamInfo += "升级成功";
                                break;
                            case "03":
                                eventLog.strEventParamInfo += "升级失败";
                                break;
                            default:
                                break;
                        }
                    }
                    break;
                case E_EventID.LevelOutput_Event:
                    {
                        //Byte0：请求源，详见附表，Byte1：通道（1，2）
                        //Byte2-3：亮度值(0-10000)
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);
                        string strByte1 = strEventParam.Substring(4, 2);
                        string strByte2 = strEventParam.Substring(2, 2);
                        string strByte3 = strEventParam.Substring(0, 2);

                        string strByte2_3 = strByte2 + strByte3;

                        Byte byByte0 = GlobalFun.HexStringToByte(strByte0);
                        Byte byByte1 = GlobalFun.HexStringToByte(strByte1);
                        UInt16 usByte23 = GlobalFun.HexStringToUInt16(strByte2_3);

                        eventLog.strEventParamInfo = "请求源: [" + (byByte0).ToString() + "]" + ((E_Oper_Src)byByte0).ToDescription();
                        eventLog.strEventParamInfo += "\r\n通道_" + byByte1.ToString() + ",亮度值: " + usByte23.ToString();
                    }
                    break;
                case E_EventID.OnOff_Event:
                    {
                        //Byte0：请求源，详见附表，Byte1：通道（1,2），Byte2：开关值
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);
                        string strByte1 = strEventParam.Substring(4, 2);
                        string strByte2 = strEventParam.Substring(2, 2);

                        Byte byByte0 = GlobalFun.HexStringToByte(strByte0);
                        Byte byByte1 = GlobalFun.HexStringToByte(strByte1);
                        Byte byByte2 = GlobalFun.HexStringToByte(strByte2);

                        eventLog.strEventParamInfo = "请求源: [" + (byByte0).ToString() + "]";
                        eventLog.strEventParamInfo += ((E_Oper_Src)byByte0).ToDescription();
                        eventLog.strEventParamInfo += "\r\n通道_";
                        eventLog.strEventParamInfo += byByte1.ToString() + ",开关值:" + byByte2.ToString();
                    }
                    break;
                case E_EventID.ADC_Vol_10V_Event:
                    {
                        //Byte0-3：本次值，0.1V
                        string strEventParam = eventLog.unEventParam.ToString("X8");

                        eventLog.strEventParamInfo = "本次值: " + GlobalFun.HexStringToUInt32(strEventParam) + " (0.1V)";
                    }
                    break;
                case E_EventID.ADC_Cur_20mA_Event:
                    {
                        //Byte0-3：本次电流值，mA
                        string strEventParam = eventLog.unEventParam.ToString("X8");

                        eventLog.strEventParamInfo = "本次值: " + GlobalFun.HexStringToUInt32(strEventParam) + " (mA)";
                    }
                    break;
                case E_EventID.ADC_Pow_5W_Event:
                    {
                        //yte0-3：本次功率值，0.1mW
                        string strEventParam = eventLog.unEventParam.ToString("X8");

                        eventLog.strEventParamInfo = "本次值: " + GlobalFun.HexStringToUInt32(strEventParam) + " (0.1mV)";
                    }
                    break;
                case E_EventID.IDC_Cur_20mA_Event:
                    {
                        //Byte0-3：本次电流值，mA
                        string strEventParam = eventLog.unEventParam.ToString("X8");

                        eventLog.strEventParamInfo = "本次值: " + GlobalFun.HexStringToUInt32(strEventParam) + " (mA)";
                    }
                    break;
                case E_EventID.Alarm_Event:
                    {
                        //Byte0-1：告警事件，见下文，Byte2：告警状态(0:恢复，1：发生) 
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);
                        string strByte1 = strEventParam.Substring(4, 2);

                        //Byte byByte0 = GlobalFun.HexStringToByte(strByte0);
                        //Byte byByte1 = GlobalFun.HexStringToByte(strByte1);
                        //UInt16 usByte23 = GlobalFun.HexStringToByte(strByte2_3);

                        eventLog.strEventParamInfo = "告警事件: 0x" + strByte0;//事件定义是啥？ 王涛
                        eventLog.strEventParamInfo += "\r\n告警状态: ";
                        eventLog.strEventParamInfo += strByte1 == "00" ? "恢复" : "发生";
                    }
                    break;
                case E_EventID.DevInitError_Event:
                    {
                        //Byte0：模块，Byte1：故障类型
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);
                        string strByte1 = strEventParam.Substring(4, 2);

                        //Byte byByte0 = GlobalFun.HexStringToByte(strByte0);
                        //Byte byByte1 = GlobalFun.HexStringToByte(strByte1);
                        //UInt16 usByte23 = GlobalFun.HexStringToByte(strByte2_3);

                        eventLog.strEventParamInfo = "设备初始化故障，模块: " + strByte0;
                        eventLog.strEventParamInfo += "\r\n故障类型: " + strByte1;
                    }
                    break;
                case E_EventID.DevRunError_Event:
                    {
                        //Byte0：模块，Byte1：故障类型（防止大量冲刷，慎用）
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);
                        string strByte1 = strEventParam.Substring(4, 2);

                        //Byte byByte0 = GlobalFun.HexStringToByte(strByte0);
                        //Byte byByte1 = GlobalFun.HexStringToByte(strByte1);
                        //UInt16 usByte23 = GlobalFun.HexStringToByte(strByte2_3);

                        eventLog.strEventParamInfo = "设备运行故障，模块: " + strByte0;
                        eventLog.strEventParamInfo += "\r\n故障类型: " + strByte1;
                    }
                    break;
                case E_EventID.LogOutofMemoryError_Event:
                    {
                        //无
                        string strEventParam = eventLog.unEventParam.ToString("X8");

                        eventLog.strEventParamInfo = "参数: " + strEventParam;
                    }
                    break;
                case E_EventID.NB_Rssi_5dbm_Event:
                    {
                        //Byte0-3:（int）RSRP值（防止大量冲刷）
                        string strEventParam = eventLog.unEventParam.ToString("X8");

                        eventLog.strEventParamInfo = "RSRP值: " + GlobalFun.HexStringToUInt32(strEventParam);
                    }
                    break;
                case E_EventID.NB_Rsrp_10_Event:
                    {
                        //Byte0-3:（int）SNR信噪比（防止大量冲刷）
                        string strEventParam = eventLog.unEventParam.ToString("X8");

                        eventLog.strEventParamInfo = "SNR值: " + GlobalFun.HexStringToUInt32(strEventParam);
                    }
                    break;
                case E_EventID.Inside_Switch_Event:
                    {
                        //Byte0：通道（0,1），Byte2：开关状态（0：关，1：开）
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);
                        string strByte1 = strEventParam.Substring(4, 2);

                        Byte byByte0 = GlobalFun.HexStringToByte(strByte0);
                        //Byte byByte1 = GlobalFun.HexStringToByte(strByte1);
                        //UInt16 usByte23 = GlobalFun.HexStringToByte(strByte2_3);

                        eventLog.strEventParamInfo = "通道_" + byByte0.ToString();
                        eventLog.strEventParamInfo += "\r\n开关状态: ";
                        eventLog.strEventParamInfo += strByte1 == "00" ? "关" : "开";
                    }
                    break;
                case E_EventID.Inside_PWM_Event:
                    {
                        //Byte0：通道（0,1），Byte2-3：leve值（0-1000）（防止渐变冲刷）
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);
                        string strByte1 = strEventParam.Substring(4, 2);
                        string strByte2 = strEventParam.Substring(2, 2);
                        string strByte12 = strByte1 + strByte2;

                        Byte byByte0 = GlobalFun.HexStringToByte(strByte0);
                        //Byte byByte1 = GlobalFun.HexStringToByte(strByte1);
                        //UInt16 usByte23 = GlobalFun.HexStringToByte(strByte2_3);

                        eventLog.strEventParamInfo = "通道_" + byByte0.ToString();
                        eventLog.strEventParamInfo += "\r\nleve值: " + GlobalFun.HexStringToUInt16(strByte12);
                    }
                    break;
                case E_EventID.StartSaveHisRunTime_Event:
                    {
                        //Byte0-4：历史运行时间，单位分钟
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        //逆序一次                        
                        //strEventParam = new string(strEventParam.ToCharArray().Reverse().ToArray());
                        //传输时是大端，含义还要转换为小端                        
                        UInt32 usParamValue = GlobalFun.HexStringToUInt32(strEventParam);
                        byte[] bytes = BitConverter.GetBytes(eventLog.unEventParam);
                        //Array.Reverse(bytes);
                        strEventParam = GlobalFun.ByteArrayToHexString(bytes);

                        eventLog.strEventParamInfo = "开始保存历史运行时间: " + GlobalFun.HexStringToUInt32(strEventParam) + " M";
                    }
                    break;
                case E_EventID.NB_LinkNet_Info1_Event:
                    {
                        //Byte0-4：cellid
                        string strEventParam = eventLog.unEventParam.ToString("X8");

                        eventLog.strEventParamInfo = "cellid: " + GlobalFun.HexStringToUInt32(strEventParam);
                    }
                    break;
                case E_EventID.NB_LinkNet_Info2_Event:
                    {
                        //Byte0-1 : snr，Byte2-3:rsrp
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);
                        string strByte1 = strEventParam.Substring(4, 2);
                        string strByte01 = strByte0 + strByte1;

                        string strByte2 = strEventParam.Substring(2, 2);
                        string strByte3 = strEventParam.Substring(0, 2);
                        string strByte23 = strByte2 + strByte3;

                        //Byte byByte0 = GlobalFun.HexStringToByte(strByte0);
                        //Byte byByte1 = GlobalFun.HexStringToByte(strByte1);
                        //UInt16 usByte23 = GlobalFun.HexStringToByte(strByte2_3);

                        eventLog.strEventParamInfo = "SNR: " + GlobalFun.HexStringToUInt16(strByte01);
                        eventLog.strEventParamInfo += "\r\nRsrp: " + GlobalFun.HexStringToUInt16(strByte23);
                    }
                    break;
                case E_EventID.NB_LinkNet_Info3_Event:
                    {
                        //Byte0-1 : earfcn
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);
                        string strByte1 = strEventParam.Substring(4, 2);
                        string strByte01 = strByte0 + strByte1;
                        //string strByte23 = strEventParam.Substring(0, 4);

                        //Byte byByte0 = GlobalFun.HexStringToByte(strByte0);
                        //Byte byByte1 = GlobalFun.HexStringToByte(strByte1);
                        //UInt16 usByte23 = GlobalFun.HexStringToByte(strByte2_3);

                        eventLog.strEventParamInfo = "Earfcn: " + GlobalFun.HexStringToUInt16(strByte01);
                        //eventLog.strEventParamInfo += "\r\nRsrp: " + GlobalFun.HexStringToUInt16(strByte23);
                    }
                    break;
                case E_EventID.IOT_Link_Status_Event:
                    {
                        //Byte0 : 0:断开连接，1连接成功。Byte1 : LWM2M Event
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);
                        string strByte1 = strEventParam.Substring(4, 2);

                        Byte byByte0 = GlobalFun.HexStringToByte(strByte0);
                        Byte byByte1 = GlobalFun.HexStringToByte(strByte1);
                        //UInt16 usByte23 = GlobalFun.HexStringToByte(strByte2_3);

                        eventLog.strEventParamInfo = "IOT连接状态: [" + (byByte0).ToString() + "]";
                        eventLog.strEventParamInfo += (strByte0 == "00" ? "断开连接" : "连接成功");
                        eventLog.strEventParamInfo += "\r\nLWM2M_Event: " + ((E_LWM2M_Event)byByte1).ToDescription();
                    }
                    break;
                case E_EventID.NB_GetNetAndHisRunTime_Event:
                    {
                        //Byte0-4：历史运行时间，单位分钟
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        //逆序一次                        
                        //strEventParam = new string(strEventParam.ToCharArray().Reverse().ToArray());
                        UInt32 usParamValue = GlobalFun.HexStringToUInt32(strEventParam);
                        byte[] bytes = BitConverter.GetBytes(eventLog.unEventParam);
                        //Array.Reverse(bytes);
                        strEventParam = GlobalFun.ByteArrayToHexString(bytes);

                        eventLog.strEventParamInfo = "获取网络和历史运行时间: " + GlobalFun.HexStringToUInt32(strEventParam) + " M";
                    }
                    break;
                case E_EventID.NB_SendData_Timeout_Event:
                    {
                        //Byte0-1：最近一次发送数据失败错误码
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);
                        string strByte1 = strEventParam.Substring(4, 2);
                        string strByte01 = strByte0 + strByte1;

                        //Byte byByte0 = GlobalFun.HexStringToByte(strByte0);
                        //Byte byByte1 = GlobalFun.HexStringToByte(strByte1);
                        UInt16 usByte01 = GlobalFun.HexStringToByte(strByte01);

                        eventLog.strEventParamInfo = "最近一次发送数据失败错误码: " + ((E_NB_SendData_Error)usByte01).ToDescription();
                    }
                    break;
                case E_EventID.NB_SendData_First_Timeout_Event:
                    {
                        //Byte0-1：同一个数据包NB首次发送失败错误码
                        string strEventParam = eventLog.unEventParam.ToString("X8");
                        string strByte0 = strEventParam.Substring(6, 2);
                        string strByte1 = strEventParam.Substring(4, 2);
                        string strByte01 = strByte0 + strByte1;

                        //Byte byByte0 = GlobalFun.HexStringToByte(strByte0);
                        //Byte byByte1 = GlobalFun.HexStringToByte(strByte1);
                        UInt16 usByte01 = GlobalFun.HexStringToByte(strByte01);

                        eventLog.strEventParamInfo = "同一个数据包NB首次发送失败错误码: " + ((E_NB_SendData_Error)usByte01).ToDescription();
                    }
                    break;
                default:
                    break;
            }
            return true;
        }
    }
}
